package SBD.CRUD;

import SBD.Servicios.Conexion;
import SBD.Servicios.FactoriaServicios;
import EP.Ontologia.Ontologia;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* @class OntologiaBD
* @author Mauricio Alvarez.
* @brief Realiza las operaciones de CRUD correspondientes a la Ontología.
*/
public class OntologiaBD
{

    /**
     *  @var private int radio
     *  @brief Valor del radio para el linkeo de terminos dentro de la ontología.
    */
    private int radio = 1;


    //////////////////////////
    // OPERACIONES
    //////////////////////////

    /**
     * @brief Guarda los terminos del XML de la ontología en la BD.
     * @param El Map de la ontología.
     * @return void
    */
    public void GuardarOntologia(Map<Integer, Ontologia> ontologia) throws java.lang.ClassNotFoundException, java.lang.InstantiationException, java.lang.IllegalAccessException, java.sql.SQLException, Error, IOException
    {

        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();

        Map map = new HashMap();
        map = ontologia;

        for (Iterator it = map.entrySet().iterator(); it.hasNext();) {

            Map.Entry entry = (Map.Entry) it.next();
            //int id_termino = Integer.valueOf(entry.getKey().toString());
            Object values = entry.getValue();
            Ontologia claseTermino = new Ontologia();
            claseTermino = (Ontologia) values;

            int id_padre = claseTermino.getId_padre();
            String Termino = claseTermino.getTermino();
            String cantidad_hijos = claseTermino.getCantidad_hijos();
            int nivel = claseTermino.getNivel();

            cdb.un_sql = "INSERT INTO ONTOLOGIA (id_padre, termino , cantidad_hijos , nivel) VALUES ("+ id_padre +",'"+ Termino +"','"+ cantidad_hijos +"',"+ nivel +");";
            cdb.un_st.executeUpdate(cdb.un_sql);

        }//FIN for


    }//FIN GuardarOntologia (OK)


    /**
     * @brief Borra todos los datos de la ontología en la BD.
     * @param No tiene.
     * @return void
    */
    public void BorrarOntologia() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {
        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();
        
        //Se borra CAMINO_RAMAS:        
        cdb.un_sql = "DELETE FROM CAMINO_RAMAS;";
        cdb.un_st.executeUpdate(cdb.un_sql);
        cdb.un_sql =  "alter table CAMINO_RAMAS auto_increment=1; ";
        cdb.un_st.executeUpdate(cdb.un_sql);
        //Se borra RAMAS:
        cdb.un_sql = "DELETE FROM RAMAS;";
        cdb.un_st.executeUpdate(cdb.un_sql);
        cdb.un_sql =  "alter table RAMAS auto_increment=1; ";
        cdb.un_st.executeUpdate(cdb.un_sql);
        //Se borra ONTOLOGIA:
        cdb.un_sql = "DELETE FROM ONTOLOGIA;";
        cdb.un_st.executeUpdate(cdb.un_sql);
        cdb.un_sql =  "alter table ONTOLOGIA auto_increment=1; ";
        cdb.un_st.executeUpdate(cdb.un_sql);

    }//FIN BorrarOntologia


    /**
     * @brief Guarda las ramas subtopicos en la BD.
     * @param el concepto semilla, el Listado de id's de Conceptos por Rama_id y el Listado de Conceptos por Rama.
     * @return void
    */
    public void GuardarSubTopico(String ConceptoSemilla,
                                 int contador_ramas,
                                 List<Integer> ListadoConceptosRama_id,
                                 List<String> ListadoConceptosRama_t)
    {

        try
        {

            int id_concepto_semilla = 0;
            //flag para la rama:
            boolean flag_rama = true;

            Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();

            //////////////////////////////////////////////////////////////////
            //PASO 1: Guardar los datos en el archivo de texto:
            //////////////////////////////////////////////////////////////////
            PrintWriter fileout = new PrintWriter(new FileWriter("RAMAS_SUBTOPICOS.txt", true));
            
            fileout.println("----------------------------------");
            fileout.println("Concepto Semilla: "+ ConceptoSemilla);
            fileout.println("Rama Número: "+ contador_ramas);
            fileout.println("----------------------------------");
            fileout.println();

            for (int i=0; i < ListadoConceptosRama_t.size(); i++)
            {
                //Se setean variables:
                int id_concepto = ListadoConceptosRama_id.get(i);
                String concepto = ListadoConceptosRama_t.get(i);
                
                //Se setea el id del topico semilla:
                if (i == 0)
                {
                    id_concepto_semilla = ListadoConceptosRama_id.get(i);
                }

                ////////////////////////////////////////////////////////////////
                //VARIANTE A: Ramas aleatorias hasta nivel 3
                ////////////////////////////////////////////////////////////////
                /*if (i < 3)
                {
                    //Se guardan datos en el archivo:
                    fileout.println((i+1) + ". id concepto: " + id_concepto);
                    fileout.println((i+1) + ". Termino:     " + concepto);
                }
                */
                ////////////////////////////////////////////////////////////////
                //VARIANTE B: Ramas aleatorias y nivel aleatorio
                ////////////////////////////////////////////////////////////////
                //Se guardan datos en el archivo:
                fileout.println((i+1) + ". id concepto: " + id_concepto);
                fileout.println((i+1) + ". Termino:     " + concepto);

                
                //////////////////////////////////////////////////////////////////
                //PASO 2: Guardar los datos en la BD en la tabla RAMAS:
                // Opcion 1: se guarda <id_topico_principal, id_concepto_hoja>
                //////////////////////////////////////////////////////////////////

                //Variante 1:
                if (flag_rama==true)
                {
                    ////////////////////////////////////////////////////////////
                    //VARIANTE 1: Sin HCH como tópico principal:
                    ////////////////////////////////////////////////////////////
                    int id_concepto_aux = ListadoConceptosRama_id.get(ListadoConceptosRama_id.size()-1);

                    ////////////////////////////////////////////////////////////
                    //VARIANTE 2: Con HCH como tópico principal:
                    ////////////////////////////////////////////////////////////
                    /*
                    int id_concepto_aux;
                    if(ListadoConceptosRama_id.size() < 3){
                        id_concepto_aux = ListadoConceptosRama_id.get(ListadoConceptosRama_id.size()-1);
                    }else{
                        id_concepto_aux = ListadoConceptosRama_id.get(2);
                    }
                    */
                    cdb.un_sql = "INSERT INTO RAMAS (id_termino, ont_id_termino) VALUES ('"+ id_concepto_semilla +"','"+ id_concepto_aux +"');";
                    cdb.un_st.executeUpdate(cdb.un_sql);
                    flag_rama = false;

                }

                //////////////////////////////////////////////////////////////////
                //PASO 3: Guardar los datos en la BD en la tabla CAMINO_RAMAS:
                //////////////////////////////////////////////////////////////////

                ////////////////////////////////////////////////////////////////
                //VARIANTE A: Ramas aleatorias hasta nivel 3
                ////////////////////////////////////////////////////////////////
                /*if (i < 3)
                {
                    cdb.un_sql = "INSERT INTO CAMINO_RAMAS (id_rama, id_termino ) VALUES ('"+ contador_ramas +"','"+ id_concepto +"');";
                    cdb.un_st.executeUpdate(cdb.un_sql);
                }
                */
                ////////////////////////////////////////////////////////////////
                //VARIANTE B: Ramas aleatorias y nivel aleatorio
                ////////////////////////////////////////////////////////////////
                cdb.un_sql = "INSERT INTO CAMINO_RAMAS (id_rama, id_termino ) VALUES ('"+ contador_ramas +"','"+ id_concepto +"');";
                cdb.un_st.executeUpdate(cdb.un_sql);

            }

            fileout.println();
            //Se cierra el archivo:
            fileout.close();

        } catch (Exception e) {
            System.err.println("ERROR: No se ha podido crear archivo de ramas sub-tópicos.");
        }
        

    }//FIN GuardarSubTopico


    /**
     * @brief Borra todas las ramas subtopicos en la BD.
     * @param No tiene.
     * @return void
    */
    public void BorrarSubtopicos() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {
        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();
        cdb.un_sql = "DELETE FROM CAMINO_RAMAS;";
        cdb.un_st.executeUpdate(cdb.un_sql);
        cdb.un_sql =  "alter table CAMINO_RAMAS auto_increment=1; ";
        cdb.un_st.executeUpdate(cdb.un_sql);
        cdb.un_sql = "DELETE FROM RAMAS;";
        cdb.un_st.executeUpdate(cdb.un_sql);
        cdb.un_sql =  "alter table RAMAS auto_increment=1; ";
        cdb.un_st.executeUpdate(cdb.un_sql);
    }


    /**
     * @brief Conecta los terminos de la ontología que no tienen padre.
     * @param No tiene.
     * @return List<Ontologia>
    */
    public List<Ontologia> ConectarTerminos() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {
        //Evaluacion de casos conocidos en la ontología:
        //Caso 1: Cuando el id_padre = id_termino:

        //Datos columnas ontología:
        int id_termino;
        int id_padre;
        String termino;
        String cantidad_hijos;
        int nivel;

        
        List<Ontologia> terminosAislados = new ArrayList();

        /////////////////////////////////////////////////
        //PASO 1: Se seleccionan los terminos aislados:
        /////////////////////////////////////////////////
        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();
        cdb.un_sql = "SELECT * FROM ONTOLOGIA WHERE id_termino = id_padre";
        cdb.resultado = cdb.un_st.executeQuery(cdb.un_sql);

        //Si hay terminos se almacenan en un arreglo:
        if (cdb.resultado != null)
        {
            while (cdb.resultado.next())
            {
                id_termino = cdb.resultado.getInt("id_termino");
                id_padre = cdb.resultado.getInt("id_padre");
                termino = cdb.resultado.getString("Termino");
                cantidad_hijos = cdb.resultado.getString("cantidad_hijos");
                nivel = cdb.resultado.getInt("nivel");

                System.out.println("--------- TERMINO CON id_termino = id_padre ------------------");
                System.out.println("id_termino: "+ id_termino);
                System.out.println("id_padre: "+ id_padre);
                System.out.println("termino: "+ termino);
                System.out.println("cantidad_hijos: "+ cantidad_hijos);
                System.out.println("nivel: "+ nivel);
                System.out.println("---------------------------");

                Ontologia ontologia = new Ontologia();
                ontologia.setId_termino(id_termino);
                ontologia.setId_padre(id_padre);
                ontologia.setTermino(termino);
                ontologia.setCantidad_hijos(cantidad_hijos);
                ontologia.setNivel(nivel);
                terminosAislados.add(ontologia);

            }
        }

        return terminosAislados;

    }//FIN ConectarTerminos


    /**
     * @brief Conecta los terminos de la ontología con un padre del nivel superior.
     * @param Listado de terminos aislados.
     * @return void
    */
    public void ConectarConPadre(List<Ontologia> terminosAislados) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {

        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();

        //Datos columnas ontología:
        int id_termino;
        int id_padre;
        String termino;
        String cantidad_hijos;
        int nivel;

        ///////////////////////////////////////////////////////////
        //PASO 2: Se enlaza con los terminos del nivel anterior
        ///////////////////////////////////////////////////////////
        for (int i = 0; i < terminosAislados.size(); i++)
        {
            int id_padre_new = 0;

            id_termino = terminosAislados.get(i).getId_termino();
            id_padre = terminosAislados.get(i).getId_padre();
            termino = terminosAislados.get(i).getTermino();
            cantidad_hijos = terminosAislados.get(i).getCantidad_hijos();
            nivel = terminosAislados.get(i).getNivel();

            if ((nivel-1) > 1 )
            {
                cdb.un_sql = "SELECT id_termino FROM ONTOLOGIA WHERE nivel = "+ (nivel-1);
                cdb.resultado = cdb.un_st.executeQuery(cdb.un_sql);

                //HashMap de ids de nivel superior:
                Map<Integer,Integer> indiceSup = new HashMap();

                if (cdb.resultado != null)
                {
                    while (cdb.resultado.next())
                    {
                        //Se guardan los ids en el Map:
                        int id_termino_nivel_up = cdb.resultado.getInt("id_termino");
                        indiceSup.put(id_termino_nivel_up, null);
                    }
                }

                //Se usan radios para establecer a que padre enlazar el termino:

                boolean flag = false;

                while(flag == false)
                {
                    //Subiendo en los terminos:
                    id_padre_new = id_padre-radio;
                    if (indiceSup.containsKey(id_padre_new) == true)
                    {
                        flag=true;
                    }else{
                        //Bajando en los terminos:
                        id_padre_new = id_padre+radio;
                        if (indiceSup.containsKey(id_padre_new) == true)
                        {
                            flag=true;
                        }
                    }
                    radio++;
                }

                radio = 1;
                ActualizarPadres(id_padre_new, id_termino);
            }

        }//FIN for

    }//FIN ConectarConPadre


    /**
     * @brief Conecta los terminos repetidos de la ontología con el termino original.
     * @param No tiene.
     * @return void
    */
    public void CorregirTerminosRepetidos() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {

        //Datos columnas ontología:
        int id_termino_ori;
        int id_termino_cop;
        int id_padre_ori;
        int id_padre_cop;
        String termino;

        List<List> terminosRepetidos = new ArrayList();

        /////////////////////////////////////////////////
        //PASO 1: Se seleccionan los terminos repetidos:
        /////////////////////////////////////////////////
        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();
        cdb.un_sql = "SELECT min(id_termino) AS id_termino_ori, "+
                     "max(id_termino) AS id_termino_cop, "+
                     "min(id_padre) AS id_padre_ori, "+
                     "max(id_padre) AS id_padre_cop, "+
                     "termino FROM ONTOLOGIA GROUP BY termino HAVING count(*) > 1;";
        cdb.resultado = cdb.un_st.executeQuery(cdb.un_sql);

        List filasTerminosRepetidos;

        //Si hay terminos se almacenan en un arreglo:
        if (cdb.resultado != null)
        {
            while (cdb.resultado.next())
            {
                id_termino_ori = cdb.resultado.getInt("id_termino_ori");
                id_termino_cop = cdb.resultado.getInt("id_termino_cop");
                id_padre_ori = cdb.resultado.getInt("id_padre_ori");
                id_padre_cop = cdb.resultado.getInt("id_padre_cop");
                termino = cdb.resultado.getString("Termino");

                System.out.println("--------- TERMINO REPETIDOS ------------------");
                System.out.println("id_termino_ori: "+ id_termino_ori);
                System.out.println("id_termino_cop: "+ id_termino_cop);
                System.out.println("id_padre_ori: "+ id_padre_ori);
                System.out.println("id_padre_cop: "+ id_padre_cop);
                System.out.println("termino: "+ termino);
                System.out.println("---------------------------");

                filasTerminosRepetidos = new ArrayList();

                filasTerminosRepetidos.add(id_termino_ori);
                filasTerminosRepetidos.add(id_termino_cop);
                filasTerminosRepetidos.add(id_padre_ori);
                filasTerminosRepetidos.add(id_padre_cop);
                filasTerminosRepetidos.add(termino);

                terminosRepetidos.add(filasTerminosRepetidos);

            }
        }

        //Se recorren todos los terminos que se repiten y se corrigen los
        //id_padre de los duplicados:
        for (int i = 0; i < terminosRepetidos.size(); i++)
        {
            
            id_termino_ori = (Integer) terminosRepetidos.get(i).get(0);
            id_termino_cop = (Integer) terminosRepetidos.get(i).get(1);
            id_padre_ori = (Integer) terminosRepetidos.get(i).get(2);
            id_padre_cop = (Integer) terminosRepetidos.get(i).get(3);
            termino = (String) terminosRepetidos.get(i).get(4);
                    
            ActualizarPadres(id_termino_ori, id_termino_cop);
        }
        
    }//FIN CargarTerminosRepetidos


    /**
     * @brief Corrige los terminos padres-hijos con problemas de niveles incorrectos.
     * @param No tiene.
     * @return List<Ontologia>
    */
    public List<Ontologia> CorregirTerminosNivelPadre() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {
        //Datos columnas ontología:
        int id_termino;
        int id_padre;
        String termino;
        String cantidad_hijos;
        int nivel;


        List<Ontologia> terminosPorCorregir = new ArrayList();

        /////////////////////////////////////////////////
        //PASO 1: Se seleccionan los terminos a corregir:
        /////////////////////////////////////////////////
        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();
        cdb.un_sql = "SELECT o1.ID_TERMINO, o1.ID_PADRE, o1.TERMINO, o1.CANTIDAD_HIJOS, o1.NIVEL "+
                     "FROM ONTOLOGIA AS o1 "+
                     "INNER JOIN ONTOLOGIA AS o2 "+
                     "ON o1.ID_TERMINO <> o2.ID_PADRE "+
                     "WHERE o1.NIVEL <= o2.NIVEL "+
                     "AND o1.ID_PADRE = o2.ID_TERMINO "+
                     ";";
        cdb.resultado = cdb.un_st.executeQuery(cdb.un_sql);

        //Si hay terminos se almacenan en un arreglo:
        if (cdb.resultado != null)
        {
            while (cdb.resultado.next())
            {
                id_termino = cdb.resultado.getInt("o1.id_termino");
                id_padre = cdb.resultado.getInt("o1.id_padre");
                termino = cdb.resultado.getString("o1.Termino");
                cantidad_hijos = cdb.resultado.getString("o1.cantidad_hijos");
                nivel = cdb.resultado.getInt("o1.nivel");

                System.out.println("--------- TERMINOS CON PROBLEMAS DE NIVEL ------------------");
                System.out.println("id_termino: "+ id_termino);
                System.out.println("id_padre: "+ id_padre);
                System.out.println("termino: "+ termino);
                System.out.println("cantidad_hijos: "+ cantidad_hijos);
                System.out.println("nivel: "+ nivel);
                System.out.println("---------------------------");

                Ontologia ontologia = new Ontologia();
                ontologia.setId_termino(id_termino);
                ontologia.setId_padre(id_padre);
                ontologia.setTermino(termino);
                ontologia.setCantidad_hijos(cantidad_hijos);
                ontologia.setNivel(nivel);
                terminosPorCorregir.add(ontologia);

            }
        }

        return terminosPorCorregir;

    }//FIN CorregirTerminosNivelPadre


    /**
     * @brief Corrige los terminos padres-hijos con problemas de niveles incorrectos.
     * @param No tiene.
     * @return List<Ontologia>
    */
    public List<Ontologia> CorregirDiferenciaNiveles() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {
        //Datos columnas ontología:
        int id_termino;
        int id_padre;
        String termino;
        String cantidad_hijos;
        int nivel;

        List<Ontologia> terminosPorCorregir = new ArrayList();

        /////////////////////////////////////////////////
        //PASO 1: Se seleccionan los terminos a corregir:
        /////////////////////////////////////////////////
        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();

        cdb.un_sql = "SELECT o1.ID_TERMINO, o1.ID_PADRE, o1.TERMINO, o1.CANTIDAD_HIJOS, o1.NIVEL "+
                     "FROM ONTOLOGIA AS o1 "+
                     "INNER JOIN ONTOLOGIA AS o2 "+
                     "ON o1.ID_TERMINO <> o2.ID_PADRE "+
                     "WHERE "+
                     "ABS(o1.NIVEL - o2.NIVEL) > 1 "+
                     "AND o1.ID_PADRE = o2.ID_TERMINO;";
        
        cdb.resultado = cdb.un_st.executeQuery(cdb.un_sql);

        //Si hay terminos se almacenan en un arreglo:
        if (cdb.resultado != null)
        {
            while (cdb.resultado.next())
            {
                id_termino = cdb.resultado.getInt("o1.id_termino");
                id_padre = cdb.resultado.getInt("o1.id_padre");
                termino = cdb.resultado.getString("o1.Termino");
                cantidad_hijos = cdb.resultado.getString("o1.cantidad_hijos");
                nivel = cdb.resultado.getInt("o1.nivel");

                System.out.println("--------- TERMINOS CON PROBLEMAS DE DIFERENCIA DE NIVEL ------------------");
                System.out.println("id_termino: "+ id_termino);
                System.out.println("id_padre: "+ id_padre);
                System.out.println("termino: "+ termino);
                System.out.println("cantidad_hijos: "+ cantidad_hijos);
                System.out.println("nivel: "+ nivel);
                System.out.println("---------------------------");

                Ontologia ontologia = new Ontologia();
                ontologia.setId_termino(id_termino);
                ontologia.setId_padre(id_padre);
                ontologia.setTermino(termino);
                ontologia.setCantidad_hijos(cantidad_hijos);
                ontologia.setNivel(nivel);
                terminosPorCorregir.add(ontologia);

            }
        }

        return terminosPorCorregir;

    }//FIN CorregirDiferenciaNiveles


    /**
     * @brief Actualiza el padre de un concepto de la ontología.
     * @param id_padre y id_termino.
     * @return void
    */
    public void ActualizarPadres(int id_padre, int id_termino) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException, IOException
    {
        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();
        cdb.un_sql = "UPDATE ONTOLOGIA SET id_padre = '" + id_padre + "' WHERE id_termino = '" + id_termino +"';";
        cdb.un_st.executeUpdate(cdb.un_sql);

    }//FIN ActualizarPadres


    /**
     * @brief Carga la ontología desde la BD.
     * @param No tiene.
     * @return Map<String,List>
    */
    public Map<String,List> CargarOntologia() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {

        String terminoOntologia;
        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();

        /////////////////////////////////////////////////////////////////////////////////
        //PASO 1:  Se define una estructura tipo "lista invertida" para la ontología
        //         donde se tiene: <Termino> --> <fila1>,<fila2>,... correspondiente
        //         a la BD.
        /////////////////////////////////////////////////////////////////////////////////
        Map<String,List> ontologia = new HashMap<String,List>();
        List<Ontologia> ListadoTerminos;

        /////////////////////////////////////////////////////////////////////////////////
        //PASO 2: Se realiza la consulta y se guardan las filas en la estructura definida
        /////////////////////////////////////////////////////////////////////////////////
        cdb.un_sql = "SELECT * FROM ONTOLOGIA;";

        cdb.resultado = cdb.un_st.executeQuery(cdb.un_sql);
        if (cdb.resultado != null)
        {
            while (cdb.resultado.next())
            {
                //Se consulta si el termino ya EXISTE en la ontología. De ser
                //así, se agrega a la lista del termino, sino se ingresa por
                //1era vez:

                terminoOntologia = cdb.resultado.getString("termino").toLowerCase().replaceAll("á", "a").replaceAll("é", "e").replaceAll("í", "i").replaceAll("ó", "o").replaceAll("ú", "u");

                if (ontologia.containsKey(terminoOntologia) == false)
                {  
                    //Se ingresa por primera vez:
                    Ontologia onto = new Ontologia();
                    ListadoTerminos = new ArrayList<Ontologia>();
                    onto.setId_termino(cdb.resultado.getInt("id_termino"));
                    onto.setId_padre(cdb.resultado.getInt("id_padre"));
                    onto.setTermino(cdb.resultado.getString("termino"));
                    onto.setCantidad_hijos(cdb.resultado.getString("cantidad_hijos"));
                    onto.setNivel(cdb.resultado.getInt("nivel"));

                    ListadoTerminos.add(onto);
                    ontologia.put(cdb.resultado.getString("termino").toLowerCase().replaceAll("á", "a").replaceAll("é", "e").replaceAll("í", "i").replaceAll("ó", "o").replaceAll("ú", "u"),ListadoTerminos);

                }else{

                    //El termino ya existe:
                    Ontologia onto = new Ontologia();
                    onto.setId_termino(cdb.resultado.getInt("id_termino"));
                    onto.setId_padre(cdb.resultado.getInt("id_padre"));
                    onto.setTermino(cdb.resultado.getString("termino"));
                    onto.setCantidad_hijos(cdb.resultado.getString("cantidad_hijos"));
                    onto.setNivel(cdb.resultado.getInt("nivel"));

                    ontologia.get(terminoOntologia).add(onto);
                }

            }
        }else{
            //Generación de error
            //throw new Error(-1, "Consulta a Registro " + p.getUrl() + "a devuelto un recorset null. Ubicación= " +
            //        this.getClass().getName());
        }

        return ontologia;

    }//FIN CargarOntologia


    /**
     * @brief Actualiza el número de descendientes de un término en la ontología.
     * @param id_termino y el numero de descendientes.
     * @return void
    */
    public void ActualizarDescendientes(int id_termino, int N_descendientes) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {
        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();
        cdb.un_sql = "UPDATE ONTOLOGIA SET cantidad_hijos = '" + N_descendientes + "' WHERE id_termino = '" + id_termino +"';";
        cdb.un_st.executeUpdate(cdb.un_sql);
    }//FIN ActualizarDescendientes

    
    /**
     * @brief Desciende de nivel a los terminos que no son tópicos y estan en el nivel 1 de la ontología.
     * @param no tiene.
     * @return List<Ontologia>
    */
    public List<Ontologia> TerminosNoTopicosNivel1() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {
        //Datos columnas ontología:
        int id_termino;
        int id_padre;
        String termino;
        String cantidad_hijos;
        int nivel;

        List<Ontologia> terminosPorCorregir = new ArrayList();

        /////////////////////////////////////////////////
        //PASO 1: Se seleccionan los terminos a corregir:
        /////////////////////////////////////////////////
        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();

        cdb.un_sql = "SELECT * FROM ontologia WHERE termino NOT like '%ambito%' AND nivel=1;";
        cdb.resultado = cdb.un_st.executeQuery(cdb.un_sql);

        //Si hay terminos se almacenan en un arreglo:
        if (cdb.resultado != null)
        {
            while (cdb.resultado.next())
            {
                id_termino = cdb.resultado.getInt("id_termino");
                id_padre = cdb.resultado.getInt("id_padre");
                termino = cdb.resultado.getString("Termino");
                cantidad_hijos = cdb.resultado.getString("cantidad_hijos");
                nivel = cdb.resultado.getInt("nivel");

                System.out.println("--------- TERMINOS NO TOPICOS QUE ESTAN EN NIVEL 1 ------------------");
                System.out.println("id_termino: "+ id_termino);
                System.out.println("id_padre: "+ id_padre);
                System.out.println("termino: "+ termino);
                System.out.println("cantidad_hijos: "+ cantidad_hijos);
                System.out.println("nivel: "+ nivel);
                System.out.println("---------------------------");

                Ontologia ontologia = new Ontologia();
                ontologia.setId_termino(id_termino);
                ontologia.setId_padre(id_padre);
                ontologia.setTermino(termino);
                ontologia.setCantidad_hijos(cantidad_hijos);
                ontologia.setNivel(nivel);
                terminosPorCorregir.add(ontologia);

            }
        }

        return terminosPorCorregir;

    }//FIN TerminosNoTopicosNivel1


    /**
     * @brief Actualiza el nivel de los terminos que no son tópicos y estan en el nivel 1.
     * @param Listado de TerminosNoTopicosNivel1.
     * @return void
    */
    public void ActualizarNivelTerminosNoTopicos(List<Ontologia> TerminosNoTopicosNivel1) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {
        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();

        for (int i=0; i<TerminosNoTopicosNivel1.size(); i++)
        {
            cdb.un_sql = "UPDATE ONTOLOGIA SET nivel = '" + 2 + "' WHERE id_termino = '" + TerminosNoTopicosNivel1.get(i).getId_termino() +"';";
            cdb.un_st.executeUpdate(cdb.un_sql);

            ///////////////////////////////////////////////////////////////////////////
            //REPARACIÓN MANUAL DEL PROBLEMA 6:
            // Se debe tener presente que esta mejora está establecida para el
            // orden de reparación de errores que se establece en la clase
            // ontología. Cambios en el orden de las instrucciones puede alterar
            // el resultado, por lo que nada garantiza que los updates aquí puestos
            // sirvan en otros casos.
            ///////////////////////////////////////////////////////////////////////////

            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2304 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1 WHERE `ID_TERMINO`=2305 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1656 WHERE `ID_TERMINO`=2306 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2307 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2308 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2309 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2310 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2311 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1656 WHERE `ID_TERMINO`=2312 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2313 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1 WHERE `ID_TERMINO`=2314 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1 WHERE `ID_TERMINO`=2315 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2316 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2317 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1 WHERE `ID_TERMINO`=2318 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2319 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2320 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2321 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2322 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2323 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2324 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2325 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2326 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2327 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2328 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2329 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2330 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2331 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2332 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2333 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2334 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1656 WHERE `ID_TERMINO`=2335 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2336 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2337 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2338 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2339 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2340 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2341 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1 WHERE `ID_TERMINO`=2342 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2343 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2344 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2345 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2346 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2347 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1 WHERE `ID_TERMINO`=2348 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1 WHERE `ID_TERMINO`=2349 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2350 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2351 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2352 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2353 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2354 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2355 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2356 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1656 WHERE `ID_TERMINO`=2357 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2358 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2359 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2360 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2361 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2418 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2420 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2421 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1 WHERE `ID_TERMINO`=2422 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2423 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2424 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2425 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2426 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2427 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2428 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2429 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2430 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2431 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2432 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1656 WHERE `ID_TERMINO`=2433 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1656 WHERE `ID_TERMINO`=2432 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2434 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1 WHERE `ID_TERMINO`=2435 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2436 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2437 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2439 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2440 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2441 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2442 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2443 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2444 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2445 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2446 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2447 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2448 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2449 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1656 WHERE `ID_TERMINO`=2450 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2451 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2452 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1656 WHERE `ID_TERMINO`=2454 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1656 WHERE `ID_TERMINO`=2455 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1656 WHERE `ID_TERMINO`=2456 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2457 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2458 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2459 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2460 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2461 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1656 WHERE `ID_TERMINO`=2462 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2463 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2417 WHERE `ID_TERMINO`=2464 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1 WHERE `ID_TERMINO`=2465 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2466 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2467 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2468 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2469 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2470 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2471 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2472 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2473 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2474 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2475 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1 WHERE `ID_TERMINO`=2476 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1 WHERE `ID_TERMINO`=2477 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2478 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1656 WHERE `ID_TERMINO`=2479 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2480 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2481 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2413 WHERE `ID_TERMINO`=2482 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2483 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2484 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=1 WHERE `ID_TERMINO`=2485 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2486 LIMIT 1";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2487 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2406 WHERE `ID_TERMINO`=2488 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);
            cdb.un_sql = "UPDATE `ontologia` SET `ID_PADRE`=2414 WHERE `ID_TERMINO`=2489 LIMIT 1;";
            cdb.un_st.executeUpdate(cdb.un_sql);

        }

    }//FIN ActualizarNivelTerminosNoTopicos


    /**
     * @brief Asciende al nivel 1 los terminos que son tópicos y que ese encuentren en niveles inferiores.
     * @param No tiene.
     * @return List<Ontologia>
    */
    public List<Ontologia> AscenderTopicosPrincipales() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {
        //Datos columnas ontología:
        int id_termino;
        int id_padre;
        String termino;
        String cantidad_hijos;
        int nivel;

        List<Ontologia> terminosPorCorregir = new ArrayList();

        /////////////////////////////////////////////////
        //PASO 1: Se seleccionan los terminos a corregir:
        /////////////////////////////////////////////////
        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();

        cdb.un_sql = "SELECT * FROM ontologia WHERE termino like '%ambito%' AND nivel>2;";
        cdb.resultado = cdb.un_st.executeQuery(cdb.un_sql);

        //Si hay terminos se almacenan en un arreglo:
        if (cdb.resultado != null)
        {
            while (cdb.resultado.next())
            {
                id_termino = cdb.resultado.getInt("id_termino");
                id_padre = cdb.resultado.getInt("id_padre");
                termino = cdb.resultado.getString("Termino");
                cantidad_hijos = cdb.resultado.getString("cantidad_hijos");
                nivel = cdb.resultado.getInt("nivel");

                System.out.println("6. --------- TOPICOS PRINCIPALES QUE ESTAN EN NIVEL > 1 ------------------");
                System.out.println("id_termino: "+ id_termino);
                System.out.println("id_padre: "+ id_padre);
                System.out.println("termino: "+ termino);
                System.out.println("cantidad_hijos: "+ cantidad_hijos);
                System.out.println("nivel: "+ nivel);
                System.out.println("---------------------------");

                Ontologia ontologia = new Ontologia();
                ontologia.setId_termino(id_termino);
                ontologia.setId_padre(id_padre);
                ontologia.setTermino(termino);
                ontologia.setCantidad_hijos(cantidad_hijos);
                ontologia.setNivel(nivel);
                terminosPorCorregir.add(ontologia);

            }
        }

        return terminosPorCorregir;

    }//FIN AscenderTopicosPrincipales


    /**
     * @brief Asciende al nivel 1 los terminos que son tópicos y que ese encuentren en niveles inferiores.
     * @param Listado de Ascenso de Topicos Principales.
     * @return void
    */
    public void ActualizarNivelTerminosTopicos(List<Ontologia> AscenderTopicosPrincipales) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {
        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();

        for (int i=0; i<AscenderTopicosPrincipales.size(); i++)
        {
            cdb.un_sql = "UPDATE ONTOLOGIA SET nivel = '" + 1 + "' WHERE id_termino = '" + AscenderTopicosPrincipales.get(i).getId_termino() +"';";
            cdb.un_st.executeUpdate(cdb.un_sql);
        }

        ////////////////////////////////////////////////////////////////////////
        //VARIACIÓN 1: Sin considerar Historia de chile
        ////////////////////////////////////////////////////////////////////////

        cdb.un_sql = "UPDATE ONTOLOGIA SET id_padre = 0 WHERE id_termino = '1656';";
        cdb.un_st.executeUpdate(cdb.un_sql);


        ////////////////////////////////////////////////////////////////////////
        //VARIACIÓN 2 (08-06-2011): Se crea el concepto "Historia de Chile" el
        //cual será padre de los, antes, tópicos principales (6).
        ////////////////////////////////////////////////////////////////////////

        //Se ingresa el Tópico "Historia de Chile":
        //cdb.un_sql = "INSERT INTO ONTOLOGIA (id_padre, termino , cantidad_hijos , nivel) VALUES ("+ 0 +",'Historia de Chile','"+ 7 +"',"+ 0 +");";
        //cdb.un_st.executeUpdate(cdb.un_sql);

        //Se actualizan los tópicos de los ex-tópicos principales:

        //Ambito social:
        //cdb.un_sql = "UPDATE ONTOLOGIA SET id_padre = 2490 WHERE id_termino = '1';";
        //cdb.un_st.executeUpdate(cdb.un_sql);
        //Ambito publico:
        //cdb.un_sql = "UPDATE ONTOLOGIA SET id_padre = 2490 WHERE id_termino = '1656';";
        //cdb.un_st.executeUpdate(cdb.un_sql);
        //Ambito cultural:
        //cdb.un_sql = "UPDATE ONTOLOGIA SET id_padre = 2490 WHERE id_termino = '2406';";
        //cdb.un_st.executeUpdate(cdb.un_sql);
        //Ambito económico:
        //cdb.un_sql = "UPDATE ONTOLOGIA SET id_padre = 2490 WHERE id_termino = '2413';";
        //cdb.un_st.executeUpdate(cdb.un_sql);
        //Ambito político:
        //cdb.un_sql = "UPDATE ONTOLOGIA SET id_padre = 2490 WHERE id_termino = '2414';";
        //cdb.un_st.executeUpdate(cdb.un_sql);
        //Ambito geográfico:
        //cdb.un_sql = "UPDATE ONTOLOGIA SET id_padre = 2490 WHERE id_termino = '2417';";
        //cdb.un_st.executeUpdate(cdb.un_sql);

        //Se aumentan los niveles en +1:
        //cdb.un_sql = "UPDATE ONTOLOGIA SET NIVEL = NIVEL + 1;";
        //cdb.un_st.executeUpdate(cdb.un_sql);

    }//FIN ActualizarNivelTerminosTopicos

    
    
    
    ////////////////////////////////////////////////////////////////////////////
    // OPERACIONES RAMAS                                                      //
    ////////////////////////////////////////////////////////////////////////////




    /**
     * @brief Entrega el numero de conceptos que pertenecen a un nivel de la
     * ontología.
     * @param Nivel de la ontología.
     * @return int
    */
    public int ContarConceptosNivel(int Nivel) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {

        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();
        int ContadorConceptos = 0;

        //Se realiza la consulta:
        cdb.un_sql = "SELECT "+
                     "COUNT(*) AS CONCEPTOS_EN_NIVEL "+
                     "FROM CAMINO_RAMAS AS cr INNER JOIN ONTOLOGIA AS o "+
                     "ON cr.ID_TERMINO = o.ID_TERMINO "+
                     "WHERE "+
                     "o.NIVEL = " + Nivel;
        cdb.resultado = cdb.un_st.executeQuery(cdb.un_sql);

        //Si hay terminos se almacenan en un arreglo:
        if (cdb.resultado != null)
        {
            while (cdb.resultado.next())
            {
                ContadorConceptos = cdb.resultado.getInt("CONCEPTOS_EN_NIVEL");
            }
        }

        return ContadorConceptos;

    }//FIN ContarConceptosNivel



    /**
     * @brief Extrae las ramas muestreadas para la prueba según (%).
     * @param Cantidad de Conceptos del nivel y la tasa de muestreo.
     * @return List<Integer>
    */
    public List<Integer> ExtraerRamasMuestreo(int Nivel, int Cantidad_Conceptos, int TasaMuestreo) throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException, IOException
    {

        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();
        List<Integer> NumeroRama = new ArrayList();

        //Se calcula el porcentaje de sampling:
        int muestreo = (int) ( (float)Cantidad_Conceptos * ( (float)TasaMuestreo/100));

        //Se realiza la consulta:
        cdb.un_sql = "SELECT "+
                       "cr.ID_CAMINO_RAMA, "
                     + "cr.ID_TERMINO AS ID_CONCEPTO_DESCENDIENTE, "
                     + "cr.ID_RAMA, "
                     + "o.NIVEL AS NIVEL_DESCENDIENTE, "
                     + "o.TERMINO "
                     + "FROM CAMINO_RAMAS AS cr INNER JOIN ONTOLOGIA AS o  "
                     + "ON cr.ID_TERMINO = o.ID_TERMINO "
                     + "WHERE "
                     + "o.NIVEL = " + Nivel
                     + " ORDER BY RAND() LIMIT "+ muestreo;

        cdb.resultado = cdb.un_st.executeQuery(cdb.un_sql);

        //Si hay terminos se almacenan en un arreglo:
        if (cdb.resultado != null)
        {
            while (cdb.resultado.next())
            {
                int N_rama = cdb.resultado.getInt("cr.ID_RAMA");
                NumeroRama.add(N_rama);
            }
        }

        return NumeroRama;

    }//FIN ExtraerRamasMuestreo


    /**
     * @brief Genera las consultas en base a las ramas subtopicos para las pruebas.
     * @param El número de la rama y el numero de ramas totales, el numero de la consulta, el nivel y la cantidad de conceptos en el nivel.
     * @return void
    */
    public void GenerarConsultaRama(int N_rama, int N_RamasTotales, int N_Consulta, int Nivel, int Cantidad_Conceptos) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, SQLException
    {

        Conexion cdb = FactoriaServicios.getInstancia().getConexionBD();

        //Teniendo las ramas sampleadas, se pueden pedir de la BD:
        //Se realiza la consulta:
        cdb.un_sql = "SELECT "
                     + "cr.ID_CAMINO_RAMA, "
                     + "cr.ID_TERMINO AS ID_CONCEPTO_DESCENDIENTE, "
                     + "cr.ID_RAMA, "
                     + "o.NIVEL AS NIVEL_DESCENDIENTE, "
                     + "o.TERMINO "
                     + "FROM CAMINO_RAMAS AS cr INNER JOIN ONTOLOGIA AS o "
                     + "ON cr.ID_TERMINO = o.ID_TERMINO "
                     + "WHERE cr.ID_RAMA = " + N_rama;

        cdb.resultado = cdb.un_st.executeQuery(cdb.un_sql);

        //Se abre el archivo de texto:
        PrintWriter fileout = new PrintWriter(new FileWriter("SUBTOPICOS_CONSULTA.txt", true));
        fileout.println("-------------------------------------");
        fileout.println("N°Rama: "+ N_rama);
        fileout.println("N°Consulta: "+ (N_Consulta+1) + "/" + N_RamasTotales);
        fileout.println("N°Conceptos en Nivel " + Nivel + " : "+ Cantidad_Conceptos);
        fileout.println("-------------------------------------");
        

        //Si hay terminos se guardan en un archivo de texto:
        if (cdb.resultado != null)
        {
            while (cdb.resultado.next())
            {
                String concepto = cdb.resultado.getString("o.TERMINO");
                fileout.println(concepto + " ");
            }
        }

        //Se cierra el archivo de texto:
        fileout.println();
        fileout.close();

    }//FIN GenerarConsultaRama


}//FIN CLASE OntologiaBD